Forgotten files
authorMatthias Clasen <matthiasc@src.gnome.org>
Sun, 11 Sep 2005 05:43:19 +0000 (05:43 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Sun, 11 Sep 2005 05:43:19 +0000 (05:43 +0000)
gtk/gtkcellrendereraccel.c [new file with mode: 0644]
gtk/gtkcellrendereraccel.h [new file with mode: 0644]
gtk/gtkcellrendererkeys.c [new file with mode: 0644]
gtk/gtkcellrendererkeys.h [new file with mode: 0644]

diff --git a/gtk/gtkcellrendereraccel.c b/gtk/gtkcellrendereraccel.c
new file mode 100644 (file)
index 0000000..38a16a6
--- /dev/null
@@ -0,0 +1,611 @@
+/* gtkcellrendererkeys.h
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "gtkintl.h"
+#include "gtkaccelgroup.h"
+#include "gtkmarshalers.h"
+#include "gtkcellrendererkeys.h"
+#include "gtklabel.h"
+#include "gtkeventbox.h"
+#include "gtkprivate.h"
+#include "gdk/gdkkeysyms.h"
+#include "gtkalias.h"
+
+
+static void             gtk_cell_renderer_keys_finalize      (GObject             *object);
+static GtkCellEditable *gtk_cell_renderer_keys_start_editing (GtkCellRenderer          *cell,
+                                                             GdkEvent                 *event,
+                                                             GtkWidget                *widget,
+                                                             const gchar              *path,
+                                                             GdkRectangle             *background_area,
+                                                             GdkRectangle             *cell_area,
+                                                             GtkCellRendererState      flags);
+
+static void gtk_cell_renderer_keys_get_property (GObject         *object,
+                                                guint            param_id,
+                                                GValue          *value,
+                                                GParamSpec      *pspec);
+static void gtk_cell_renderer_keys_set_property (GObject         *object,
+                                                guint            param_id,
+                                                const GValue    *value,
+                                                GParamSpec      *pspec);
+static void gtk_cell_renderer_keys_get_size     (GtkCellRenderer *cell,
+                                                GtkWidget       *widget,
+                                                GdkRectangle    *cell_area,
+                                                gint            *x_offset,
+                                                gint            *y_offset,
+                                                gint            *width,
+                                                gint            *height);
+
+enum {
+  ACCEL_EDITED,
+  ACCEL_CLEARED,
+  LAST_SIGNAL
+};
+
+enum {
+  PROP_0,
+  PROP_ACCEL_KEY,
+  PROP_ACCEL_MODS,
+  PROP_KEYCODE,
+  PROP_ACCEL_MODE
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GtkCellRendererKeys, gtk_cell_renderer_keys, GTK_TYPE_CELL_RENDERER_TEXT);
+
+static void
+gtk_cell_renderer_keys_init (GtkCellRendererKeys *cell_keys)
+{
+}
+
+static void
+gtk_cell_renderer_keys_class_init (GtkCellRendererKeysClass *cell_keys_class)
+{
+  GObjectClass *object_class;
+  GtkCellRendererClass *cell_renderer_class;
+
+  object_class = G_OBJECT_CLASS (cell_keys_class);
+  cell_renderer_class = GTK_CELL_RENDERER_CLASS (cell_keys_class);
+  
+  GTK_CELL_RENDERER_CLASS (cell_keys_class)->start_editing = gtk_cell_renderer_keys_start_editing;
+
+  object_class->set_property = gtk_cell_renderer_keys_set_property;
+  object_class->get_property = gtk_cell_renderer_keys_get_property;
+  cell_renderer_class->get_size = gtk_cell_renderer_keys_get_size;
+
+  object_class->finalize = gtk_cell_renderer_keys_finalize;
+
+  /**
+   * GtkCellRendererKeys:accel-key:
+   *
+   * The keyval of the accelerator.
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_ACCEL_KEY,
+                                   g_param_spec_uint ("accel-key",
+                                                     P_("Accelerator key"),
+                                                     P_("The keyval of the accelerator"),
+                                                      0,
+                                                      G_MAXINT,
+                                                      0,
+                                                      GTK_PARAM_READWRITE));
+  
+  /**
+   * GtkCellRendererKeys:accel-mods:
+   *
+   * The modifier mask of the accelerator.
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_ACCEL_MODS,
+                                   g_param_spec_flags ("accel-mods",
+                                                       P_("Accelerator modifiers"),
+                                                       P_("The modifier mask of the accelerator"),
+                                                       GDK_TYPE_MODIFIER_TYPE,
+                                                       0,
+                                                       GTK_PARAM_READWRITE));
+
+  /**
+   * GtkCellRendererKeys:keycode:
+   *
+   * The hardware keycode of the accelerator. Note that the hardware keycode is
+   * only relevant if the key does not have a keyval. Normally, the keyboard
+   * configuration should assign keyvals to all keys.
+   *
+   * Since: 2.10
+   */ 
+  g_object_class_install_property (object_class,
+                                  PROP_KEYCODE,
+                                  g_param_spec_uint ("keycode",
+                                                     P_("Accelerator keycode"),
+                                                     P_("The hardware keycode of the accelerator"),
+                                                     0,
+                                                     G_MAXINT,
+                                                     0,
+                                                     GTK_PARAM_READWRITE));
+
+  /**
+   * GtkCellRendererKeys:accel-mode:
+   *
+   * Determines if the edited accelerators are GTK+ accelerators. If
+   * they are, consumed modifiers are suppressed, only accelerators
+   * accepted by GTK+ are allowed, and the accelerators are rendered
+   * in the same way as they are in menus.
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_ACCEL_MODE,
+                                   g_param_spec_enum ("accel-mode",
+                                                     P_("Accelerator Mode"),
+                                                     P_("The type of accelerators"),
+                                                     GTK_TYPE_CELL_RENDERER_KEYS_MODE,
+                                                     GTK_CELL_RENDERER_KEYS_MODE_GTK,
+                                                     GTK_PARAM_READWRITE));
+  
+  /**
+   * GtkCellRendererKeys::accel-edited:
+   * @keys: the object reveiving the signal
+   * @path_string: the path identifying the row of the edited cell
+   * @accel_key: the new accelerator keyval
+   * @accel_mods: the new acclerator modifier mask
+   * @hardware_keycode: the keycode of the new accelerator
+   *
+   * Gets emitted when the user has selected a new accelerator.
+   *
+   * Since: 2.10
+   */
+  signals[ACCEL_EDITED] = g_signal_new (I_("accel-edited"),
+                                       GTK_TYPE_CELL_RENDERER_KEYS,
+                                       G_SIGNAL_RUN_LAST,
+                                       G_STRUCT_OFFSET (GtkCellRendererKeysClass, accel_edited),
+                                       NULL, NULL,
+                                       _gtk_marshal_VOID__STRING_UINT_FLAGS_UINT,
+                                       G_TYPE_NONE, 4,
+                                       G_TYPE_STRING,
+                                       G_TYPE_UINT,
+                                       GDK_TYPE_MODIFIER_TYPE,
+                                       G_TYPE_UINT);
+
+  /**
+   * GtkCellRendererKeys::accel-cleared:
+   * @keys: the object reveiving the signal
+   * @path_string: the path identifying the row of the edited cell
+   *
+   * Gets emitted when the user has removed the accelerator.
+   *
+   * Since: 2.10
+   */
+  signals[ACCEL_CLEARED] = g_signal_new (I_("accel-cleared"),
+                                        GTK_TYPE_CELL_RENDERER_KEYS,
+                                        G_SIGNAL_RUN_LAST,
+                                        G_STRUCT_OFFSET (GtkCellRendererKeysClass, accel_cleared),
+                                        NULL, NULL,
+                                        g_cclosure_marshal_VOID__STRING,
+                                        G_TYPE_NONE, 1,
+                                        G_TYPE_STRING);
+}
+
+
+/**
+ * gtk_cell_renderer_keys_new:
+ *
+ * Creates a new #GtkCellRendererKeys.
+ * 
+ * Returns: the new cell renderer
+ *
+ * Since: 2.10
+ */
+GtkCellRenderer *
+gtk_cell_renderer_keys_new (void)
+{
+  return GTK_CELL_RENDERER (g_object_new (GTK_TYPE_CELL_RENDERER_KEYS, NULL));
+}
+
+static void
+gtk_cell_renderer_keys_finalize (GObject *object)
+{
+  
+  (* G_OBJECT_CLASS (gtk_cell_renderer_keys_parent_class)->finalize) (object);
+}
+
+static gchar *
+convert_keysym_state_to_string (GtkCellRendererKeys *keys,
+                               guint                keysym,
+                                GdkModifierType      mask,
+                               guint                keycode)
+{
+  if (keysym == 0 && keycode == 0)
+    /* This label is displayed in a treeview cell displaying
+     * a disabled accelerator key combination. Only include
+     * the text after the | in the translation.
+     */
+    return g_strdup (Q_("Accelerator|Disabled"));
+  else 
+    {
+      if (keys->accel_mode == GTK_CELL_RENDERER_KEYS_MODE_GTK)
+       return gtk_accelerator_get_label (keysym, mask);
+      else 
+       {
+         gchar *name;
+
+         name = gtk_accelerator_name (keysym, mask);
+         if (keysym == 0)
+           {
+             gchar *tmp;
+
+             tmp = name;
+             name = g_strdup_printf ("%s0x%02x", tmp, keycode);
+             g_free (tmp);
+           }
+
+         return name;
+       }
+    }
+}
+
+static void
+gtk_cell_renderer_keys_get_property  (GObject    *object,
+                                      guint       param_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  GtkCellRendererKeys *keys;
+
+  g_return_if_fail (GTK_IS_CELL_RENDERER_KEYS (object));
+
+  keys = GTK_CELL_RENDERER_KEYS (object);
+  
+  switch (param_id)
+    {
+    case PROP_ACCEL_KEY:
+      g_value_set_uint (value, keys->accel_key);
+      break;
+
+    case PROP_ACCEL_MODS:
+      g_value_set_flags (value, keys->accel_mods);
+      break;
+
+    case PROP_ACCEL_MODE:
+      g_value_set_enum (value, keys->accel_mode);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+    }
+}
+
+static void
+gtk_cell_renderer_keys_set_property  (GObject      *object,
+                                      guint         param_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  GtkCellRendererKeys *keys;
+  gboolean changed = FALSE;
+
+  g_return_if_fail (GTK_IS_CELL_RENDERER_KEYS (object));
+
+  keys = GTK_CELL_RENDERER_KEYS (object);
+  
+  switch (param_id)
+    {
+    case PROP_ACCEL_KEY:
+      {
+       guint accel_key = g_value_get_uint (value);
+
+       if (keys->accel_key != accel_key)
+         {
+           keys->accel_key = accel_key;
+           changed = TRUE;
+         }
+      }
+      break;
+
+    case PROP_ACCEL_MODS:
+      {
+       guint accel_mods = g_value_get_flags (value);
+
+       if (keys->accel_mods != accel_mods)
+         {
+           keys->accel_mods = accel_mods;
+           changed = TRUE;
+         }
+      }
+      break;
+    case PROP_KEYCODE:
+      {
+       guint keycode = g_value_get_uint (value);
+
+       if (keys->keycode != keycode)
+         {
+           keys->keycode = keycode;
+           changed = TRUE;
+         }
+      }
+      break;
+
+    case PROP_ACCEL_MODE:
+      keys->accel_mode = g_value_get_enum (value);
+      break;
+      
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+    }
+
+  if (changed)
+    {
+      GtkCellRendererText *celltext;
+      gchar *text;
+
+      celltext = GTK_CELL_RENDERER_TEXT (keys);
+      text = convert_keysym_state_to_string (keys, keys->accel_key, keys->accel_mods, keys->keycode);
+      g_object_set (keys, "text", text, NULL);
+      g_free (text);
+    }
+}
+
+static void
+gtk_cell_renderer_keys_get_size (GtkCellRenderer *cell,
+                                GtkWidget       *widget,
+                                GdkRectangle    *cell_area,
+                                gint            *x_offset,
+                                gint            *y_offset,
+                                gint            *width,
+                                gint            *height)
+
+{
+  GtkCellRendererKeys *keys = (GtkCellRendererKeys *) cell;
+  GtkRequisition requisition;
+
+  if (keys->sizing_label == NULL)
+    keys->sizing_label = gtk_label_new (_("New accelerator..."));
+
+  gtk_widget_size_request (keys->sizing_label, &requisition);
+  (* GTK_CELL_RENDERER_CLASS (gtk_cell_renderer_keys_parent_class)->get_size) (cell, widget, cell_area, 
+                                                                              x_offset, y_offset, width, height);
+  /* FIXME: need to take the cell_area et al. into account */
+  if (width)
+    *width = MAX (*width, requisition.width);
+  if (height)
+    *height = MAX (*height, requisition.height);
+}
+
+static gboolean
+grab_key_callback (GtkWidget    *widget,
+                   GdkEventKey  *event,
+                   void         *data)
+{
+  GdkModifierType accel_mods = 0;
+  guint accel_key;
+  GtkCellRendererKeys *keys;
+  char *path;
+  gboolean edited;
+  gboolean cleared;
+  GdkModifierType consumed_modifiers;  
+  GdkDisplay *display;
+  
+  keys = GTK_CELL_RENDERER_KEYS (data);
+
+  display = gtk_widget_get_display (widget);
+  
+  if (event->is_modifier)
+    return TRUE;
+
+  edited = FALSE;
+  cleared = FALSE;
+
+  gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display),
+                                      event->hardware_keycode,
+                                       event->state,
+                                       event->group,
+                                      NULL, NULL, NULL, &consumed_modifiers);
+
+  accel_key = gdk_keyval_to_lower (event->keyval);
+  if (accel_key == GDK_ISO_Left_Tab) 
+    accel_key = GDK_Tab;
+
+  accel_mods = event->state & gtk_accelerator_get_default_mod_mask ();
+
+  /* Filter consumed modifiers 
+   */
+  if (keys->accel_mode == GTK_CELL_RENDERER_KEYS_MODE_GTK)
+    accel_mods &= ~consumed_modifiers;
+  
+  /* Put shift back if it changed the case of the key, not otherwise.
+   */
+  if (accel_key != event->keyval)
+    accel_mods |= GDK_SHIFT_MASK;
+    
+  if (accel_mods == 0)
+    {
+      switch (event->keyval)
+       {
+       case GDK_Escape:
+         goto out; /* cancel */
+       case GDK_BackSpace:
+         /* clear the accelerator on Backspace */
+         cleared = TRUE;
+         goto out;
+       default:
+         break;
+       }
+    }
+
+  if (keys->accel_mode == GTK_CELL_RENDERER_KEYS_MODE_GTK)
+    {
+      if (!gtk_accelerator_valid (accel_key, accel_mods))
+       {
+         gdk_display_beep (display);
+
+         return TRUE;
+       }
+    }
+
+  edited = TRUE;
+
+ out:
+  gdk_keyboard_ungrab (event->time);
+  gdk_pointer_ungrab (event->time);
+  
+  path = g_strdup (g_object_get_data (G_OBJECT (keys->edit_widget), "gtk-cell-renderer-text"));
+
+  gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (keys->edit_widget));
+  gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (keys->edit_widget));
+  keys->edit_widget = NULL;
+  keys->grab_widget = NULL;
+  
+  if (edited)
+    g_signal_emit (keys, signals[ACCEL_EDITED], 0, path, 
+                  accel_key, accel_mods, event->hardware_keycode);
+  else if (cleared)
+    g_signal_emit (keys, signals[ACCEL_CLEARED], 0, path);
+
+  g_free (path);
+
+  return TRUE;
+}
+
+static void
+ungrab_stuff (GtkWidget *widget, gpointer data)
+{
+  GtkCellRendererKeys *keys = GTK_CELL_RENDERER_KEYS (data);
+
+  gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+  gdk_pointer_ungrab (GDK_CURRENT_TIME);
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (keys->grab_widget),
+                                        G_CALLBACK (grab_key_callback), data);
+}
+
+static void
+_gtk_cell_editable_event_box_start_editing (GtkCellEditable *cell_editable,
+                                           GdkEvent        *event)
+{
+  /* do nothing, because we are pointless */
+}
+
+static void
+_gtk_cell_editable_event_box_cell_editable_init (GtkCellEditableIface *iface)
+{
+  iface->start_editing = _gtk_cell_editable_event_box_start_editing;
+}
+
+typedef GtkEventBox      GtkCellEditableEventBox;
+typedef GtkEventBoxClass GtkCellEditableEventBoxClass;
+
+G_DEFINE_TYPE_WITH_CODE (GtkCellEditableEventBox, _gtk_cell_editable_event_box, GTK_TYPE_EVENT_BOX, { \
+    G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE, _gtk_cell_editable_event_box_cell_editable_init)   \
+      });
+
+
+static void
+_gtk_cell_editable_event_box_class_init (GtkCellEditableEventBoxClass *class)
+{
+}
+
+static void
+_gtk_cell_editable_event_box_init (GtkCellEditableEventBox *box)
+{
+}
+
+static GtkCellEditable *
+gtk_cell_renderer_keys_start_editing (GtkCellRenderer      *cell,
+                                     GdkEvent             *event,
+                                     GtkWidget            *widget,
+                                     const gchar          *path,
+                                     GdkRectangle         *background_area,
+                                     GdkRectangle         *cell_area,
+                                     GtkCellRendererState  flags)
+{
+  GtkCellRendererText *celltext;
+  GtkCellRendererKeys *keys;
+  GtkWidget *label;
+  GtkWidget *eventbox;
+  
+  celltext = GTK_CELL_RENDERER_TEXT (cell);
+  keys = GTK_CELL_RENDERER_KEYS (cell);
+
+  /* If the cell isn't editable we return NULL. */
+  if (celltext->editable == FALSE)
+    return NULL;
+
+  g_return_val_if_fail (widget->window != NULL, NULL);
+  
+  if (gdk_keyboard_grab (widget->window, FALSE,
+                         gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+    return NULL;
+
+  if (gdk_pointer_grab (widget->window, FALSE,
+                        GDK_BUTTON_PRESS_MASK,
+                        NULL, NULL,
+                        gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+    {
+      gdk_keyboard_ungrab (gdk_event_get_time (event));
+      return NULL;
+    }
+  
+  keys->grab_widget = widget;
+
+  g_signal_connect (G_OBJECT (widget), "key_press_event",
+                    G_CALLBACK (grab_key_callback),
+                    keys);
+
+  eventbox = g_object_new (_gtk_cell_editable_event_box_get_type (), NULL);
+  keys->edit_widget = eventbox;
+  g_object_add_weak_pointer (G_OBJECT (keys->edit_widget),
+                             (void**) &keys->edit_widget);
+  
+  label = gtk_label_new (NULL);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  
+  gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL,
+                        &widget->style->bg[GTK_STATE_SELECTED]);
+
+  gtk_widget_modify_fg (label, GTK_STATE_NORMAL,
+                        &widget->style->fg[GTK_STATE_SELECTED]);
+  
+  /* This label is displayed in a treeview cell displaying
+   * an accelerator when the cell is clicked to change the 
+   * acelerator.
+   */
+  gtk_label_set_text (GTK_LABEL (label), _("New accelerator..."));
+
+  gtk_container_add (GTK_CONTAINER (eventbox), label);
+  
+  g_object_set_data_full (G_OBJECT (keys->edit_widget), "gtk-cell-renderer-text",
+                          g_strdup (path), g_free);
+  
+  gtk_widget_show_all (keys->edit_widget);
+
+  g_signal_connect (G_OBJECT (keys->edit_widget), "unrealize",
+                    G_CALLBACK (ungrab_stuff), keys);
+  
+  return GTK_CELL_EDITABLE (keys->edit_widget);
+}
+
+
+#define __GTK_CELL_RENDERER_KEYS_C__
+#include "gtkaliasdef.c"
diff --git a/gtk/gtkcellrendereraccel.h b/gtk/gtkcellrendereraccel.h
new file mode 100644 (file)
index 0000000..6ec3829
--- /dev/null
@@ -0,0 +1,88 @@
+/* gtkcellrendererkeys.h
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_CELL_RENDERER_KEYS_H__
+#define __GTK_CELL_RENDERER_KEYS_H__
+
+#include "gtkcellrenderertext.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CELL_RENDERER_KEYS            (gtk_cell_renderer_keys_get_type ())
+#define GTK_CELL_RENDERER_KEYS(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_CELL_RENDERER_KEYS, GtkCellRendererKeys))
+#define GTK_CELL_RENDERER_KEYS_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_CELL_RENDERER_KEYS, GtkCellRendererKeysClass))
+#define GTK_IS_CELL_RENDERER_KEYS(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_CELL_RENDERER_KEYS))
+#define GTK_IS_CELL_RENDERER_KEYS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CELL_RENDERER_KEYS))
+#define GTK_CELL_RENDERER_KEYS_GET_CLASS(obj)   (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_CELL_RENDERER_KEYS, GtkCellRendererKeysClass))
+
+typedef struct _GtkCellRendererKeys      GtkCellRendererKeys;
+typedef struct _GtkCellRendererKeysClass GtkCellRendererKeysClass;
+
+
+typedef enum
+{
+  GTK_CELL_RENDERER_KEYS_MODE_GTK,
+  GTK_CELL_RENDERER_KEYS_MODE_OTHER
+} GtkCellRendererKeysMode;
+
+
+struct _GtkCellRendererKeys
+{
+  GtkCellRendererText parent;
+
+  /*< private >*/
+  guint accel_key;
+  GdkModifierType accel_mods;
+  guint keycode;
+  GtkCellRendererKeysMode accel_mode;
+
+  GtkWidget *edit_widget;
+  GtkWidget *grab_widget;
+  GtkWidget *sizing_label;
+};
+
+struct _GtkCellRendererKeysClass
+{
+  GtkCellRendererTextClass parent_class;
+
+  void (* accel_edited)  (GtkCellRendererKeys *keys,
+                         const gchar         *path_string,
+                         guint                accel_key,
+                         GdkModifierType      accel_mods,
+                         guint                hardware_keycode);
+
+  void (* accel_cleared) (GtkCellRendererKeys *keys,
+                         const gchar         *path_string);
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved0) (void);
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+};
+
+GType            gtk_cell_renderer_keys_get_type        (void) G_GNUC_CONST;
+GtkCellRenderer *gtk_cell_renderer_keys_new             (void);
+
+
+G_END_DECLS
+
+
+#endif /* __GTK_CELL_RENDERER_KEYS_H__ */
diff --git a/gtk/gtkcellrendererkeys.c b/gtk/gtkcellrendererkeys.c
new file mode 100644 (file)
index 0000000..38a16a6
--- /dev/null
@@ -0,0 +1,611 @@
+/* gtkcellrendererkeys.h
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "gtkintl.h"
+#include "gtkaccelgroup.h"
+#include "gtkmarshalers.h"
+#include "gtkcellrendererkeys.h"
+#include "gtklabel.h"
+#include "gtkeventbox.h"
+#include "gtkprivate.h"
+#include "gdk/gdkkeysyms.h"
+#include "gtkalias.h"
+
+
+static void             gtk_cell_renderer_keys_finalize      (GObject             *object);
+static GtkCellEditable *gtk_cell_renderer_keys_start_editing (GtkCellRenderer          *cell,
+                                                             GdkEvent                 *event,
+                                                             GtkWidget                *widget,
+                                                             const gchar              *path,
+                                                             GdkRectangle             *background_area,
+                                                             GdkRectangle             *cell_area,
+                                                             GtkCellRendererState      flags);
+
+static void gtk_cell_renderer_keys_get_property (GObject         *object,
+                                                guint            param_id,
+                                                GValue          *value,
+                                                GParamSpec      *pspec);
+static void gtk_cell_renderer_keys_set_property (GObject         *object,
+                                                guint            param_id,
+                                                const GValue    *value,
+                                                GParamSpec      *pspec);
+static void gtk_cell_renderer_keys_get_size     (GtkCellRenderer *cell,
+                                                GtkWidget       *widget,
+                                                GdkRectangle    *cell_area,
+                                                gint            *x_offset,
+                                                gint            *y_offset,
+                                                gint            *width,
+                                                gint            *height);
+
+enum {
+  ACCEL_EDITED,
+  ACCEL_CLEARED,
+  LAST_SIGNAL
+};
+
+enum {
+  PROP_0,
+  PROP_ACCEL_KEY,
+  PROP_ACCEL_MODS,
+  PROP_KEYCODE,
+  PROP_ACCEL_MODE
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GtkCellRendererKeys, gtk_cell_renderer_keys, GTK_TYPE_CELL_RENDERER_TEXT);
+
+static void
+gtk_cell_renderer_keys_init (GtkCellRendererKeys *cell_keys)
+{
+}
+
+static void
+gtk_cell_renderer_keys_class_init (GtkCellRendererKeysClass *cell_keys_class)
+{
+  GObjectClass *object_class;
+  GtkCellRendererClass *cell_renderer_class;
+
+  object_class = G_OBJECT_CLASS (cell_keys_class);
+  cell_renderer_class = GTK_CELL_RENDERER_CLASS (cell_keys_class);
+  
+  GTK_CELL_RENDERER_CLASS (cell_keys_class)->start_editing = gtk_cell_renderer_keys_start_editing;
+
+  object_class->set_property = gtk_cell_renderer_keys_set_property;
+  object_class->get_property = gtk_cell_renderer_keys_get_property;
+  cell_renderer_class->get_size = gtk_cell_renderer_keys_get_size;
+
+  object_class->finalize = gtk_cell_renderer_keys_finalize;
+
+  /**
+   * GtkCellRendererKeys:accel-key:
+   *
+   * The keyval of the accelerator.
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_ACCEL_KEY,
+                                   g_param_spec_uint ("accel-key",
+                                                     P_("Accelerator key"),
+                                                     P_("The keyval of the accelerator"),
+                                                      0,
+                                                      G_MAXINT,
+                                                      0,
+                                                      GTK_PARAM_READWRITE));
+  
+  /**
+   * GtkCellRendererKeys:accel-mods:
+   *
+   * The modifier mask of the accelerator.
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_ACCEL_MODS,
+                                   g_param_spec_flags ("accel-mods",
+                                                       P_("Accelerator modifiers"),
+                                                       P_("The modifier mask of the accelerator"),
+                                                       GDK_TYPE_MODIFIER_TYPE,
+                                                       0,
+                                                       GTK_PARAM_READWRITE));
+
+  /**
+   * GtkCellRendererKeys:keycode:
+   *
+   * The hardware keycode of the accelerator. Note that the hardware keycode is
+   * only relevant if the key does not have a keyval. Normally, the keyboard
+   * configuration should assign keyvals to all keys.
+   *
+   * Since: 2.10
+   */ 
+  g_object_class_install_property (object_class,
+                                  PROP_KEYCODE,
+                                  g_param_spec_uint ("keycode",
+                                                     P_("Accelerator keycode"),
+                                                     P_("The hardware keycode of the accelerator"),
+                                                     0,
+                                                     G_MAXINT,
+                                                     0,
+                                                     GTK_PARAM_READWRITE));
+
+  /**
+   * GtkCellRendererKeys:accel-mode:
+   *
+   * Determines if the edited accelerators are GTK+ accelerators. If
+   * they are, consumed modifiers are suppressed, only accelerators
+   * accepted by GTK+ are allowed, and the accelerators are rendered
+   * in the same way as they are in menus.
+   *
+   * Since: 2.10
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_ACCEL_MODE,
+                                   g_param_spec_enum ("accel-mode",
+                                                     P_("Accelerator Mode"),
+                                                     P_("The type of accelerators"),
+                                                     GTK_TYPE_CELL_RENDERER_KEYS_MODE,
+                                                     GTK_CELL_RENDERER_KEYS_MODE_GTK,
+                                                     GTK_PARAM_READWRITE));
+  
+  /**
+   * GtkCellRendererKeys::accel-edited:
+   * @keys: the object reveiving the signal
+   * @path_string: the path identifying the row of the edited cell
+   * @accel_key: the new accelerator keyval
+   * @accel_mods: the new acclerator modifier mask
+   * @hardware_keycode: the keycode of the new accelerator
+   *
+   * Gets emitted when the user has selected a new accelerator.
+   *
+   * Since: 2.10
+   */
+  signals[ACCEL_EDITED] = g_signal_new (I_("accel-edited"),
+                                       GTK_TYPE_CELL_RENDERER_KEYS,
+                                       G_SIGNAL_RUN_LAST,
+                                       G_STRUCT_OFFSET (GtkCellRendererKeysClass, accel_edited),
+                                       NULL, NULL,
+                                       _gtk_marshal_VOID__STRING_UINT_FLAGS_UINT,
+                                       G_TYPE_NONE, 4,
+                                       G_TYPE_STRING,
+                                       G_TYPE_UINT,
+                                       GDK_TYPE_MODIFIER_TYPE,
+                                       G_TYPE_UINT);
+
+  /**
+   * GtkCellRendererKeys::accel-cleared:
+   * @keys: the object reveiving the signal
+   * @path_string: the path identifying the row of the edited cell
+   *
+   * Gets emitted when the user has removed the accelerator.
+   *
+   * Since: 2.10
+   */
+  signals[ACCEL_CLEARED] = g_signal_new (I_("accel-cleared"),
+                                        GTK_TYPE_CELL_RENDERER_KEYS,
+                                        G_SIGNAL_RUN_LAST,
+                                        G_STRUCT_OFFSET (GtkCellRendererKeysClass, accel_cleared),
+                                        NULL, NULL,
+                                        g_cclosure_marshal_VOID__STRING,
+                                        G_TYPE_NONE, 1,
+                                        G_TYPE_STRING);
+}
+
+
+/**
+ * gtk_cell_renderer_keys_new:
+ *
+ * Creates a new #GtkCellRendererKeys.
+ * 
+ * Returns: the new cell renderer
+ *
+ * Since: 2.10
+ */
+GtkCellRenderer *
+gtk_cell_renderer_keys_new (void)
+{
+  return GTK_CELL_RENDERER (g_object_new (GTK_TYPE_CELL_RENDERER_KEYS, NULL));
+}
+
+static void
+gtk_cell_renderer_keys_finalize (GObject *object)
+{
+  
+  (* G_OBJECT_CLASS (gtk_cell_renderer_keys_parent_class)->finalize) (object);
+}
+
+static gchar *
+convert_keysym_state_to_string (GtkCellRendererKeys *keys,
+                               guint                keysym,
+                                GdkModifierType      mask,
+                               guint                keycode)
+{
+  if (keysym == 0 && keycode == 0)
+    /* This label is displayed in a treeview cell displaying
+     * a disabled accelerator key combination. Only include
+     * the text after the | in the translation.
+     */
+    return g_strdup (Q_("Accelerator|Disabled"));
+  else 
+    {
+      if (keys->accel_mode == GTK_CELL_RENDERER_KEYS_MODE_GTK)
+       return gtk_accelerator_get_label (keysym, mask);
+      else 
+       {
+         gchar *name;
+
+         name = gtk_accelerator_name (keysym, mask);
+         if (keysym == 0)
+           {
+             gchar *tmp;
+
+             tmp = name;
+             name = g_strdup_printf ("%s0x%02x", tmp, keycode);
+             g_free (tmp);
+           }
+
+         return name;
+       }
+    }
+}
+
+static void
+gtk_cell_renderer_keys_get_property  (GObject    *object,
+                                      guint       param_id,
+                                      GValue     *value,
+                                      GParamSpec *pspec)
+{
+  GtkCellRendererKeys *keys;
+
+  g_return_if_fail (GTK_IS_CELL_RENDERER_KEYS (object));
+
+  keys = GTK_CELL_RENDERER_KEYS (object);
+  
+  switch (param_id)
+    {
+    case PROP_ACCEL_KEY:
+      g_value_set_uint (value, keys->accel_key);
+      break;
+
+    case PROP_ACCEL_MODS:
+      g_value_set_flags (value, keys->accel_mods);
+      break;
+
+    case PROP_ACCEL_MODE:
+      g_value_set_enum (value, keys->accel_mode);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+    }
+}
+
+static void
+gtk_cell_renderer_keys_set_property  (GObject      *object,
+                                      guint         param_id,
+                                      const GValue *value,
+                                      GParamSpec   *pspec)
+{
+  GtkCellRendererKeys *keys;
+  gboolean changed = FALSE;
+
+  g_return_if_fail (GTK_IS_CELL_RENDERER_KEYS (object));
+
+  keys = GTK_CELL_RENDERER_KEYS (object);
+  
+  switch (param_id)
+    {
+    case PROP_ACCEL_KEY:
+      {
+       guint accel_key = g_value_get_uint (value);
+
+       if (keys->accel_key != accel_key)
+         {
+           keys->accel_key = accel_key;
+           changed = TRUE;
+         }
+      }
+      break;
+
+    case PROP_ACCEL_MODS:
+      {
+       guint accel_mods = g_value_get_flags (value);
+
+       if (keys->accel_mods != accel_mods)
+         {
+           keys->accel_mods = accel_mods;
+           changed = TRUE;
+         }
+      }
+      break;
+    case PROP_KEYCODE:
+      {
+       guint keycode = g_value_get_uint (value);
+
+       if (keys->keycode != keycode)
+         {
+           keys->keycode = keycode;
+           changed = TRUE;
+         }
+      }
+      break;
+
+    case PROP_ACCEL_MODE:
+      keys->accel_mode = g_value_get_enum (value);
+      break;
+      
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+    }
+
+  if (changed)
+    {
+      GtkCellRendererText *celltext;
+      gchar *text;
+
+      celltext = GTK_CELL_RENDERER_TEXT (keys);
+      text = convert_keysym_state_to_string (keys, keys->accel_key, keys->accel_mods, keys->keycode);
+      g_object_set (keys, "text", text, NULL);
+      g_free (text);
+    }
+}
+
+static void
+gtk_cell_renderer_keys_get_size (GtkCellRenderer *cell,
+                                GtkWidget       *widget,
+                                GdkRectangle    *cell_area,
+                                gint            *x_offset,
+                                gint            *y_offset,
+                                gint            *width,
+                                gint            *height)
+
+{
+  GtkCellRendererKeys *keys = (GtkCellRendererKeys *) cell;
+  GtkRequisition requisition;
+
+  if (keys->sizing_label == NULL)
+    keys->sizing_label = gtk_label_new (_("New accelerator..."));
+
+  gtk_widget_size_request (keys->sizing_label, &requisition);
+  (* GTK_CELL_RENDERER_CLASS (gtk_cell_renderer_keys_parent_class)->get_size) (cell, widget, cell_area, 
+                                                                              x_offset, y_offset, width, height);
+  /* FIXME: need to take the cell_area et al. into account */
+  if (width)
+    *width = MAX (*width, requisition.width);
+  if (height)
+    *height = MAX (*height, requisition.height);
+}
+
+static gboolean
+grab_key_callback (GtkWidget    *widget,
+                   GdkEventKey  *event,
+                   void         *data)
+{
+  GdkModifierType accel_mods = 0;
+  guint accel_key;
+  GtkCellRendererKeys *keys;
+  char *path;
+  gboolean edited;
+  gboolean cleared;
+  GdkModifierType consumed_modifiers;  
+  GdkDisplay *display;
+  
+  keys = GTK_CELL_RENDERER_KEYS (data);
+
+  display = gtk_widget_get_display (widget);
+  
+  if (event->is_modifier)
+    return TRUE;
+
+  edited = FALSE;
+  cleared = FALSE;
+
+  gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display),
+                                      event->hardware_keycode,
+                                       event->state,
+                                       event->group,
+                                      NULL, NULL, NULL, &consumed_modifiers);
+
+  accel_key = gdk_keyval_to_lower (event->keyval);
+  if (accel_key == GDK_ISO_Left_Tab) 
+    accel_key = GDK_Tab;
+
+  accel_mods = event->state & gtk_accelerator_get_default_mod_mask ();
+
+  /* Filter consumed modifiers 
+   */
+  if (keys->accel_mode == GTK_CELL_RENDERER_KEYS_MODE_GTK)
+    accel_mods &= ~consumed_modifiers;
+  
+  /* Put shift back if it changed the case of the key, not otherwise.
+   */
+  if (accel_key != event->keyval)
+    accel_mods |= GDK_SHIFT_MASK;
+    
+  if (accel_mods == 0)
+    {
+      switch (event->keyval)
+       {
+       case GDK_Escape:
+         goto out; /* cancel */
+       case GDK_BackSpace:
+         /* clear the accelerator on Backspace */
+         cleared = TRUE;
+         goto out;
+       default:
+         break;
+       }
+    }
+
+  if (keys->accel_mode == GTK_CELL_RENDERER_KEYS_MODE_GTK)
+    {
+      if (!gtk_accelerator_valid (accel_key, accel_mods))
+       {
+         gdk_display_beep (display);
+
+         return TRUE;
+       }
+    }
+
+  edited = TRUE;
+
+ out:
+  gdk_keyboard_ungrab (event->time);
+  gdk_pointer_ungrab (event->time);
+  
+  path = g_strdup (g_object_get_data (G_OBJECT (keys->edit_widget), "gtk-cell-renderer-text"));
+
+  gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (keys->edit_widget));
+  gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (keys->edit_widget));
+  keys->edit_widget = NULL;
+  keys->grab_widget = NULL;
+  
+  if (edited)
+    g_signal_emit (keys, signals[ACCEL_EDITED], 0, path, 
+                  accel_key, accel_mods, event->hardware_keycode);
+  else if (cleared)
+    g_signal_emit (keys, signals[ACCEL_CLEARED], 0, path);
+
+  g_free (path);
+
+  return TRUE;
+}
+
+static void
+ungrab_stuff (GtkWidget *widget, gpointer data)
+{
+  GtkCellRendererKeys *keys = GTK_CELL_RENDERER_KEYS (data);
+
+  gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+  gdk_pointer_ungrab (GDK_CURRENT_TIME);
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (keys->grab_widget),
+                                        G_CALLBACK (grab_key_callback), data);
+}
+
+static void
+_gtk_cell_editable_event_box_start_editing (GtkCellEditable *cell_editable,
+                                           GdkEvent        *event)
+{
+  /* do nothing, because we are pointless */
+}
+
+static void
+_gtk_cell_editable_event_box_cell_editable_init (GtkCellEditableIface *iface)
+{
+  iface->start_editing = _gtk_cell_editable_event_box_start_editing;
+}
+
+typedef GtkEventBox      GtkCellEditableEventBox;
+typedef GtkEventBoxClass GtkCellEditableEventBoxClass;
+
+G_DEFINE_TYPE_WITH_CODE (GtkCellEditableEventBox, _gtk_cell_editable_event_box, GTK_TYPE_EVENT_BOX, { \
+    G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE, _gtk_cell_editable_event_box_cell_editable_init)   \
+      });
+
+
+static void
+_gtk_cell_editable_event_box_class_init (GtkCellEditableEventBoxClass *class)
+{
+}
+
+static void
+_gtk_cell_editable_event_box_init (GtkCellEditableEventBox *box)
+{
+}
+
+static GtkCellEditable *
+gtk_cell_renderer_keys_start_editing (GtkCellRenderer      *cell,
+                                     GdkEvent             *event,
+                                     GtkWidget            *widget,
+                                     const gchar          *path,
+                                     GdkRectangle         *background_area,
+                                     GdkRectangle         *cell_area,
+                                     GtkCellRendererState  flags)
+{
+  GtkCellRendererText *celltext;
+  GtkCellRendererKeys *keys;
+  GtkWidget *label;
+  GtkWidget *eventbox;
+  
+  celltext = GTK_CELL_RENDERER_TEXT (cell);
+  keys = GTK_CELL_RENDERER_KEYS (cell);
+
+  /* If the cell isn't editable we return NULL. */
+  if (celltext->editable == FALSE)
+    return NULL;
+
+  g_return_val_if_fail (widget->window != NULL, NULL);
+  
+  if (gdk_keyboard_grab (widget->window, FALSE,
+                         gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+    return NULL;
+
+  if (gdk_pointer_grab (widget->window, FALSE,
+                        GDK_BUTTON_PRESS_MASK,
+                        NULL, NULL,
+                        gdk_event_get_time (event)) != GDK_GRAB_SUCCESS)
+    {
+      gdk_keyboard_ungrab (gdk_event_get_time (event));
+      return NULL;
+    }
+  
+  keys->grab_widget = widget;
+
+  g_signal_connect (G_OBJECT (widget), "key_press_event",
+                    G_CALLBACK (grab_key_callback),
+                    keys);
+
+  eventbox = g_object_new (_gtk_cell_editable_event_box_get_type (), NULL);
+  keys->edit_widget = eventbox;
+  g_object_add_weak_pointer (G_OBJECT (keys->edit_widget),
+                             (void**) &keys->edit_widget);
+  
+  label = gtk_label_new (NULL);
+  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+  
+  gtk_widget_modify_bg (eventbox, GTK_STATE_NORMAL,
+                        &widget->style->bg[GTK_STATE_SELECTED]);
+
+  gtk_widget_modify_fg (label, GTK_STATE_NORMAL,
+                        &widget->style->fg[GTK_STATE_SELECTED]);
+  
+  /* This label is displayed in a treeview cell displaying
+   * an accelerator when the cell is clicked to change the 
+   * acelerator.
+   */
+  gtk_label_set_text (GTK_LABEL (label), _("New accelerator..."));
+
+  gtk_container_add (GTK_CONTAINER (eventbox), label);
+  
+  g_object_set_data_full (G_OBJECT (keys->edit_widget), "gtk-cell-renderer-text",
+                          g_strdup (path), g_free);
+  
+  gtk_widget_show_all (keys->edit_widget);
+
+  g_signal_connect (G_OBJECT (keys->edit_widget), "unrealize",
+                    G_CALLBACK (ungrab_stuff), keys);
+  
+  return GTK_CELL_EDITABLE (keys->edit_widget);
+}
+
+
+#define __GTK_CELL_RENDERER_KEYS_C__
+#include "gtkaliasdef.c"
diff --git a/gtk/gtkcellrendererkeys.h b/gtk/gtkcellrendererkeys.h
new file mode 100644 (file)
index 0000000..6ec3829
--- /dev/null
@@ -0,0 +1,88 @@
+/* gtkcellrendererkeys.h
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_CELL_RENDERER_KEYS_H__
+#define __GTK_CELL_RENDERER_KEYS_H__
+
+#include "gtkcellrenderertext.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_CELL_RENDERER_KEYS            (gtk_cell_renderer_keys_get_type ())
+#define GTK_CELL_RENDERER_KEYS(obj)            (GTK_CHECK_CAST ((obj), GTK_TYPE_CELL_RENDERER_KEYS, GtkCellRendererKeys))
+#define GTK_CELL_RENDERER_KEYS_CLASS(klass)    (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_CELL_RENDERER_KEYS, GtkCellRendererKeysClass))
+#define GTK_IS_CELL_RENDERER_KEYS(obj)         (GTK_CHECK_TYPE ((obj), GTK_TYPE_CELL_RENDERER_KEYS))
+#define GTK_IS_CELL_RENDERER_KEYS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CELL_RENDERER_KEYS))
+#define GTK_CELL_RENDERER_KEYS_GET_CLASS(obj)   (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_CELL_RENDERER_KEYS, GtkCellRendererKeysClass))
+
+typedef struct _GtkCellRendererKeys      GtkCellRendererKeys;
+typedef struct _GtkCellRendererKeysClass GtkCellRendererKeysClass;
+
+
+typedef enum
+{
+  GTK_CELL_RENDERER_KEYS_MODE_GTK,
+  GTK_CELL_RENDERER_KEYS_MODE_OTHER
+} GtkCellRendererKeysMode;
+
+
+struct _GtkCellRendererKeys
+{
+  GtkCellRendererText parent;
+
+  /*< private >*/
+  guint accel_key;
+  GdkModifierType accel_mods;
+  guint keycode;
+  GtkCellRendererKeysMode accel_mode;
+
+  GtkWidget *edit_widget;
+  GtkWidget *grab_widget;
+  GtkWidget *sizing_label;
+};
+
+struct _GtkCellRendererKeysClass
+{
+  GtkCellRendererTextClass parent_class;
+
+  void (* accel_edited)  (GtkCellRendererKeys *keys,
+                         const gchar         *path_string,
+                         guint                accel_key,
+                         GdkModifierType      accel_mods,
+                         guint                hardware_keycode);
+
+  void (* accel_cleared) (GtkCellRendererKeys *keys,
+                         const gchar         *path_string);
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved0) (void);
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+};
+
+GType            gtk_cell_renderer_keys_get_type        (void) G_GNUC_CONST;
+GtkCellRenderer *gtk_cell_renderer_keys_new             (void);
+
+
+G_END_DECLS
+
+
+#endif /* __GTK_CELL_RENDERER_KEYS_H__ */